package test;

import java.util.List;

import org.hibernate.HibernateException;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import trip.*;
import dao.*;

public class StopDAOTest extends Assert {
	
	private Route_stopsDAO rsD = Factory.getInstance().getRoute_stopsDAO();
	private RouteDAO rD = Factory.getInstance().getRouteDAO();
	private StopDAO sD = Factory.getInstance().getStopDAO();
	private PersonDAO pD = Factory.getInstance().getPersonDAO();
	private Person_tripDAO ptD = Factory.getInstance().getPerson_tripDAO();
	
	@DataProvider
	public Object[][] stopData() {
		return new Object[][] {
				{"test.1", true},
				{null, false},
				{"nameLengthGreaterThenMaxGREATERGREATERGREATER", false},
		};
	}
	
	@Test(dataProvider="stopData")
	public void dataTest(String name, boolean expected)	{
		try {
			Integer count = sD.getAll().size();
			assertNotNull(count);
			Stop stop = new Stop(1, name);
			sD.create(stop);
			Stop tmpStop = sD.getById(stop.getId());
			assertNotNull(tmpStop);
			assertEquals(tmpStop.getId(), stop.getId());
			assertEquals(tmpStop.getName(), stop.getName());
			stop.setName(stop.getName() + "new");
			sD.update(stop);
			tmpStop = sD.getById(stop.getId());
			assertNotNull(tmpStop);
			assertEquals(tmpStop.getId(), stop.getId());
			assertEquals(tmpStop.getName(), stop.getName());
			sD.delete(tmpStop);
			tmpStop = sD.getById(stop.getId());
			assertNull(tmpStop);
			assertEquals(sD.getAll().size(), count.intValue());
			assertTrue(expected);
		} catch (HibernateException ex) {
			assertFalse(expected);
		}
	}
	
	@Test
	public void getByRouteTest() {
		List<Stop> stops = sD.getAll();
		assertNotNull(stops);
		List<Route> routes = rD.getAll();
		assertNotNull(routes);
		List<Route_stops> rss = rsD.getAll();
		assertNotNull(rss);
		for(Route route : routes) {
			List<Stop> sByR = sD.getByRoute(route);
			assertNotNull(sByR);
			if (sByR.size() != 0) {
				for(Stop stop : sByR) {
					boolean found = false;
					for(Route_stops rs : rss) {
						if (rs.getStop().equals(stop) && rs.getRoute().equals(route)) {
							found = true;
							break;
						}
					}
					assertTrue(found);
				}
			} 
			else {
				boolean found = false;
				for(Route_stops rs : rss) {
					if (rs.getRoute().equals(route)) {
						found = true;
						break;
					}
				}
				assertFalse(found);
			}
		}
	}
	
	@Test
	public void getByPersonTest() {
		List<Stop> stops = sD.getAll();
		assertNotNull(stops);
		List<Person> persons = pD.getAll();
		assertNotNull(persons);
		List<Person_trip> pts = ptD.getAll();
		assertNotNull(pts);
		for(Person person : persons) {
			List<List<Stop>> sByP = sD.getByPerson(person);
			assertNotNull(sByP);
			if (sByP.size() != 0) {
				for(List<Stop> adstop : sByP) {
					assertNotNull(adstop);
					assertTrue(adstop.size() == 2);
					boolean found = false;
					for(Person_trip ps : pts) {
						if (ps.getDeparture_stop().equals(adstop.get(0)) &&
							ps.getArrival_stop().equals(adstop.get(1)) &&
							ps.getPerson().equals(person)) {
							found = true;
							break;
						}
					}
					assertTrue(found);
				}
			} 
			else {
				boolean found = false;
				for(Person_trip ps : pts) {
					if (ps.getPerson().equals(person)) {
						found = true;
						break;
					}
				}
				assertFalse(found);
			}
		}
	}
}